<template>
	<div class="p-10 flex-row h100">
		<div class="left system-page-background b-r-4">
			<div class="flex-row" style="border-bottom: 1px solid var(--el-border-color); padding: 12px 10px">
				<my-input placeholder="请输入名称" v-model="filterText" class="m-r-5" />
				<el-button type="primary" @click="insertFn" icon="Plus">新增</el-button>
			</div>
			<div class="f1 h0 p-10">
				<el-tree
					:data="treeList"
					:props="{
						children: 'children',
						label: 'name'
					}"
					:expand-on-click-node="false"
					:filter-node-method="filterNode"
					highlight-current
					node-key="id"
					ref="refTree"
					@node-click="handleNodeClick"
				>
					<template #default="{ data }">
						<div class="flex-row w100">
							<span class="ellipsis f1 w0">{{ data.name }}</span>
							<span>
								<my-button-text @click.stop="updateFn(data)">修改</my-button-text>
								<my-button-text @click.stop="deleteFn(data)">删除</my-button-text>
							</span>
						</div>
					</template>
				</el-tree>
			</div>
		</div>

		<div class="right system-page-background">
			<my-panel :title="operateTitle" icon="Menu" size="large" class="f1 h0" fit v-if="operate.open">
				<div class="w100 h100 flex-col">
					<my-form
						class="f1 h0 rightForm"
						ref="reForm"
						label-position="top"
						label-suffix="："
						:model="request"
						:formItem="[
							{
								label: '名称',
								prop: 'name',
								required: true
							},
							{
								label: '地址',
								prop: 'url',
								required: true
							},
							{
								label: '选择方式',
								prop: 'tabValue'
							}
						]"
					>
						<template #url>
							<setting-item name="请求方式 & URL 地址" class="w100">
								<div class="flex">
									<my-select
										style="width: 150px"
										v-model="request.httpType"
										:fileType="{ label: 'label', value: 'value' }"
										:list="[
											{ label: 'get', value: 'get' },
											{ label: 'post', value: 'post' },
											{ label: 'patch', value: 'patch' },
											{ label: 'put', value: 'put' },
											{ label: 'delete', value: 'delete' }
										]"
									/>
									<my-input v-model="request.url" bias placeholder="请输入地址" />
								</div>
							</setting-item>
						</template>
						<template #tabValue>
							<n-tabs type="line" animated v-model:value="request.tabValue" style="margin-top: -5px">
								<n-tab v-for="item in ['Params', 'Body', 'Header']" :key="item" :name="item" :tab="item">
									{{ item }}
								</n-tab>
							</n-tabs>
							<!-- 各个页面 -->
							<div class="m-t-10 w100">
								<div v-if="request.tabValue !== 'Body'">
									<request-header-table
										:target="request.params?.[request.tabValue]"
										@update="updateRequestParams"
									></request-header-table>
								</div>

								<!-- 选择了 body -->
								<div v-else>
									<n-radio-group v-model:value="request.paramsBodyType" name="radiogroup">
										<n-space>
											<n-radio
												v-for="bodyEnum in ['none', 'form-data', 'x-www-form-urlencoded', 'json', 'xml']"
												:key="bodyEnum"
												:value="bodyEnum"
											>
												{{ bodyEnum }}
											</n-radio>
										</n-space>
									</n-radio-group>

									<!-- 为 none 时 -->
									<n-card class="m-t-10" v-if="request.paramsBodyType === 'none'">
										<n-text depth="3">该接口没有 Body 体</n-text>
									</n-card>

									<!-- 具有对象属性时 -->
									<template
										v-else-if="
											request.paramsBodyType === 'form-data' || request.paramsBodyType === 'x-www-form-urlencoded'
										"
									>
										<request-header-table
											class="m-t-10"
											:target="request.params['Body'][request.paramsBodyType]"
											@update="updateRequestBodyTable"
										/>
									</template>

									<!-- json  -->
									<template v-else-if="request.paramsBodyType === 'json'">
										<my-monaco-editor
											v-model:modelValue="request.params['Body'][request.paramsBodyType]"
											width="100%"
											height="280px"
											language="json"
										/>
									</template>

									<!-- xml  -->
									<template v-else-if="request.paramsBodyType === 'xml'">
										<my-monaco-editor
											v-model:modelValue="request.params['Body'][request.paramsBodyType]"
											width="100%"
											height="280px"
											language="html"
										/>
									</template>
								</div>
							</div>
						</template>
					</my-form>
					<div class="tr" v-if="operate.name != 'detail'">
						<el-button @click="operate.open = false">取 消</el-button>
						<el-button type="primary" @click="SubmitFn()">确 定</el-button>
					</div>
				</div>
			</my-panel>
		</div>
	</div>
</template>

<script setup name="/request/outsideApi">
import { addOutApi as add, editOutApi as edit, removeOutApi as remove, listOutApi } from '@/api/data';

/********************************************************树形数据**********************************/
// 筛选节点
const refTree = shallowRef(null),
	filterText = ref('');
watch(filterText, (val) => {
	refTree.value?.filter(val);
});
function filterNode(value, data) {
	if (!value) return true;
	return data.name.includes(value);
}
// 数据
const treeList = ref([]);
function loadData() {
	listOutApi().then((res) => {
		treeList.value = res.data;
		treeList.value.some((item) => {
			item.params = JSON.parse(item.params);
		});
		const data = treeList.value[0];
		if (data) {
			handleNodeClick(data);
			nextTick(() => {
				refTree.value?.setCurrentKey(data.id);
			});
		}
	});
}
loadData();
// 删除
function deleteFn(row) {
	confirm('此操作将删除该条数据, 是否继续?')
		.then(() => {
			remove({ ids: row.id }).then(() => {
				msgSuccess('删除成功');
				loadData();
			});
		})
		.catch(() => {
			msgInfo('已取消删除！');
		});
}

// 详情
function handleNodeClick(row) {
	operate.name = 'detail';
	operate.open = true;
	nextTick(() => {
		request.value = cloneDeep(row);
	});
}

/*****************************************************右边数据***********************************/
const requestData = {
		name: '',
		httpType: 'get',
		url: '',
		tabValue: 'Params',
		paramsBodyType: 'none',
		params: {
			Body: { 'form-data': {}, 'x-www-form-urlencoded': {}, json: '', xml: '' },
			Header: {},
			Params: {}
		}
	},
	request = ref(cloneDeep(requestData));

// 更新参数表格数据
function updateRequestParams(paramsObj) {
	if (request.tabValue !== 'Body') {
		request.params[request.tabValue] = paramsObj;
	}
}

// 更新参数表格数据
function updateRequestBodyTable(paramsObj) {
	if (
		request.tabValue === 'Body' &&
		// 仅有两种类型有 body
		(request.paramsBodyType === 'form-data' || request.paramsBodyType === 'x-www-form-urlencoded')
	) {
		request.params['Body'][request.paramsBodyType] = paramsObj;
	}
}

const reForm = shallowRef(null),
	operate = reactive({});

const operateTitle = computed(() => {
	if (operate.name === 'insert') return `新增`;
	if (operate.name === 'update') return `修改-${request.value.name}`;
	if (operate.name === 'detail') return `详情-${request.value.name}`;
});

// 新增
function insertFn() {
	request.value = cloneDeep(requestData);
	operate.name = 'insert';
	operate.open = true;
	nextTick(() => {
		refTree.value?.setCurrentKey(null);
	});
}
// 修改
function updateFn(row) {
	operate.name = 'update';
	operate.open = true;
	nextTick(() => {
		request.value = cloneDeep(row);
	});
}
// 新增、修改提交逻辑
function SubmitFn() {
	reForm.value?.$refs?.refMyForm.validate((valid) => {
		if (valid) {
			const data = clone(request.value);
			(operate.name == 'insert' ? add : edit)({ ...data, params: JSON.stringify(data.params) }).then(() => {
				operate.open = false;
				msgSuccess(`${operate.name == 'insert' ? '新增成功！' : '修改成功！'}`);
				loadData();
			});
		}
	});
}
</script>

<style lang="scss" scoped>
.left {
	height: 100%;
	width: 25%;
	min-width: 350px;
	overflow: auto;
	display: flex;
	flex-direction: column;
}
.right {
	margin-left: 10px;
	height: 100%;
	flex: 1;
	display: flex;
	flex-direction: column;
	width: 0;
	.rightForm {
		:deep(.el-form-item__label) {
			margin: 20px 0 20px;
			font-size: 20px;
			color: var(--el-color-primary) !important;
		}
	}
}
</style>
